

package com.kk.score.exception;

import com.kk.score.utils.HttpConstant;
import com.kk.score.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSendException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.util.stream.Collectors;

/**
 * 异常处理器
 *
 * @author kk
 */
@RestControllerAdvice
@Slf4j
public class RRExceptionHandler {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(RRException.class)
    public R handleRRException(RRException e) {
        R r = new R();
        r.put("code", e.getCode());
        r.put("msg", e.getMessage());
        return r;
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public R handlerNoFoundException(Exception e) {
        logger.error(e.getMessage(), e);
        return R.error(404, "路径不存在，请检查路径是否正确");
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public R handleDuplicateKeyException(DuplicateKeyException e) {
        logger.error(e.getMessage(), e);
        return R.error("数据库中已存在该记录");
    }

    @ExceptionHandler(AccessDeniedException.class)
    public R handleAuthorizationException(AccessDeniedException e) {
        logger.error(e.getMessage(), e);
        return R.error(HttpConstant.用户没有权限_令牌_用户名_密码错误,"没有权限，请联系管理员授权");
    }

    @ExceptionHandler(Exception.class)
    public R handleException(Exception e) {
        logger.error(e.getMessage(), e);
        return R.error();
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public R httpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error(e.getMessage(), e);
        return R.error("json转换异常");
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R defaultErrorHandler(Exception e) {
        logger.error(e.getMessage(), e);
        return R.error(HttpConstant.请求的格式不可得, ((MethodArgumentNotValidException) e).getFieldErrors().stream().map(v -> v.getField() + ":" + v.getDefaultMessage()).collect(Collectors.joining(";")));
    }


    @ExceptionHandler(value = AuthenticationException.class)
    public R doShiroException(AuthenticationException e) {
        if (e instanceof InternalAuthenticationServiceException) {
            return R.error(HttpConstant.用户没有权限_令牌_用户名_密码错误, "用户名不存在");
        } else if (e instanceof BadCredentialsException) {
            return R.error(HttpConstant.用户没有权限_令牌_用户名_密码错误, "密码不正确");
        } else if (e instanceof LockedException) {
            return R.error(HttpConstant.用户没有权限_令牌_用户名_密码错误, "账户被锁定");
        }/* else if (e instanceof AuthorizationException) {
            return R.error(HttpConstant.用户得到授权_但是访问是被禁止的,"用户没有权限");
        } */ else {
            return R.error(HttpConstant.用户得到授权_但是访问是被禁止的, "认证或授权失败");
        }
    }

    @ExceptionHandler(value = MailException.class)
    public R handlerEmailException(MailException e) {
        if (e instanceof MailSendException) {
            return R.error(HttpConstant.发出的请求针对的是不存在的记录_服务器没有进行操作, "目标邮箱不存在！");
        } else {
            return R.error(HttpConstant.当创建一个对象时_发生一个验证错误, "文本邮件发送异常！");
        }
    }
}
